package gov.pbc.nn.kjgl.fxq.staff.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.exception.NoneLoginException;
import com.bstek.bdf2.core.service.IDeptService;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.data.variant.Record;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.core.entity.BaseEntity;
import gov.pbc.nn.kjgl.fxq.staff.entity.StaffEntity;



@Component(StaffPR.BEAN_ID)
public class StaffPR extends CommonHibernateDao {

	public static final String BEAN_ID = "staffPR";
	
	@Autowired
	@Qualifier(IDeptService.BEAN_ID)
	private IDeptService deptService;
	
	@Resource(name=PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao hibernateDao;
	
	private List<Map<String, Object>> getOrganNamesByDeptId(String deptId) throws Exception{
		Map<String, Object> map=new HashMap<String, Object>();
		map.put("deptId", deptId);
		return this.query("select new map(o.organName as name) from OrganInfor o where o.deptId=:deptId ",map);
	}

	private void saveEntity(BaseEntity entity) {
		EntityState state = EntityUtils.getState(entity);
		if (state.equals(EntityState.NEW)) {
			this.save(entity);
		} else if (state.equals(EntityState.MODIFIED)) {
			this.update(entity);
		} else if (state.equals(EntityState.DELETED)) {
			this.delete(entity);
		}
	}
	
	private List<Map<String, Object>> getAllChildDeptNames(String deptId){
		Collection<String> deptIdList = new ArrayList<String>();
		Session session = this.hibernateDao.getSessionFactory().openSession();

		try {
			Collection<String> depts = new ArrayList<String>();
			depts.add(deptId);
			deptIdList.addAll(depts);
			
			String sqlForId = "select d.ID_ from t_dept d where d.PARENT_ID_ in(:depts)";
			Query queryForId = session.createSQLQuery(sqlForId);
			while (depts != null && !depts.isEmpty()) {
				queryForId.setParameterList("depts", depts);
				depts = queryForId.list();
				deptIdList.addAll(depts);
			}
			//System.out.println(deptIdList);
			String sqlForName = "select d.NAME_ as name from t_dept d where d.ID_ in(:depts) and length(TRIM(DEPT_LEVEL_))>0";
			Query queryForName = session.createSQLQuery(sqlForName).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);;
			queryForName.setParameterList("depts", deptIdList);
			return queryForName.list();
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return null;
	}	
	
	@DataProvider
	public void loadAllStaffs(Page<StaffEntity> page, Criteria criteria) throws Exception {
		IUser user = ContextHolder.getLoginUser();
		if (user == null)
			throw new NoneLoginException("请先登录！");
		if (user.getDepts() == null || user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");

		Dept dept = (Dept) user.getDepts().get(0);
		DetachedCriteria detachedCriteria = this.buildDetachedCriteria(criteria, StaffEntity.class);
		detachedCriteria.add(Restrictions.eq("invalid", false));
		detachedCriteria.add(Restrictions.eq("deptId", dept.getCDept().getId()));
		if (criteria != null && criteria.getOrders() != null && !criteria.getOrders().isEmpty()) {
			com.bstek.dorado.data.provider.Order order = criteria.getOrders().get(0);
			if (order.isDesc()) {
				detachedCriteria.addOrder(Order.desc(order.getProperty()));
			} else {
				detachedCriteria.addOrder(Order.asc(order.getProperty()));
			}
		} else {
			detachedCriteria.addOrder(Order.desc("createDate"));
		}
		this.pagingQuery(page, detachedCriteria);
	}
	
	@DataProvider
	public List<Map<String, Object>> getOrganNames()throws Exception{
		IUser user = ContextHolder.getLoginUser();
		if (user == null)
			throw new NoneLoginException("请先登录！");
		if (user.getDepts() == null || user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");
		Dept dept = (Dept) user.getDepts().get(0);
		List<Map<String, Object>> OrganNames=this.getOrganNamesByDeptId(dept.getCDept().getId());
		Dept org= (Dept) deptService.loadDeptById(dept.getCDept().getParentId());
		OrganNames.addAll(this.getAllChildDeptNames(org.getId()));
		return OrganNames;
	}

	@DataResolver
	@Transactional
	public void saveStaffs(List<StaffEntity> staffs) throws Exception {
		IUser user = ContextHolder.getLoginUser();
		if (user == null)
			throw new NoneLoginException("请先登录！");
		if (user.getDepts() == null || user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");
		Dept dept = (Dept) user.getDepts().get(0);
		for (StaffEntity staff : staffs) {
			EntityState state = EntityUtils.getState(staff);

			if (state.equals(EntityState.NEW)) {
				staff.setDeptId(dept.getCDept().getId());
				staff.setDeptName(dept.getCDept().getName());
				this.save(staff);
			} else if (state.equals(EntityState.MODIFIED)) {
				this.update(staff);
			} else if (state.equals(EntityState.DELETED)) {
				this.delete(staff);
			}

		}

	}
}
